﻿$$.Selector = function (node, rows, val, clas, xoffset) {
	//不循环的滚轮选择器
	var Box = $("<div>").addClass("Selector");
	if (clas) Box.addClass(clas);
	Box.Val = function (value) {
		if (value === undefined) {
			if (!Cur) return {};
			return Cur.Value;
		}
		if (!value && value !== 0) return;
		selVal(value, true);
	};
	Box.HideVal = function (val) {
		var t = $.type(val);
		if (t === "array") {
			for (var i = 0; i < val.length; i++) {
				$("li[data-id='" + val[i] + "']", ul).addClass("hide");
			}
			return;
		}
		if (t === "object") {
			for (var k in val) {
				$("li[data-id='" + k + "']", ul).addClass("hide");
			}
			return;
		}
		$("li[data-id='" + val + "']", ul).addClass("hide");
	};
	Box.ShowVal = function (val) {
		if ($.type(val) === "array") {
			for (var i = 0; i < val.length; i++) {
				$("li[data-id='" + val[i] + "']", ul).removeClass("hide");
			}
			return;
		}
		if (t === "object") {
			for (var k in val) {
				$("li[data-id='" + k + "']", ul).removeClass("hide");
			}
			return;
		}
		$("li[data-id='" + val + "']", ul).removeClass("hide");
	};
	Box.ShowAll = function () {
		$("li.hide", ul).removeClass("hide");
	};

	if (!node) return Box;
	var tp = $.type(rows);
	if (tp !== "array" || rows.length < 1) {
		Box.appendTo(node);
		Box.html("数据加载失败");
		return Box;
	}

	var Stage = $("<div>").addClass("Stage").appendTo(Box);
	var ul = $("<ul>").appendTo(Stage);
	var Ul = ul[0];

	var Arr = [], Num = 0, Cur = null, Dist = 0, Heig = 20;
	var Deg = 0, Deg2 = 0, DegCur = 0, MinDist = 1, DegMax = 0, DegMin = 0;
	function render() {
		var nd;
		for (var i = 0; i < rows.length; i++) {
			var row = rows[i];
			if (!row || !(row.ID || row.ID == 0)) continue;
			nd = $("<li>").attr("data-id", row.ID + "").html(row.Name).appendTo(ul)[0];
			nd.Value = row;
			Arr.push(nd);
		}
		Box.appendTo(node);

		Num = Arr.length;
		if (Num < 1) {
			Box.html("数据为空");
			return Box;
		}

		Dist = node.clientHeight;
		Heig = Arr[0].clientHeight || Heig;

		var top = (Dist - Heig - 20) / 2;
		Stage.css({ "height": Heig + "px", "top": top + "px" });

		var z = Dist / 2 - 2;
		var perspective = z * Dist / Heig;
		var cst = "perspective:" + perspective + "px;-webkit-perspective:" + perspective + "px;";
		if (xoffset > 0 || xoffset < 0) {
			var xo = 50 - xoffset;
			cst += "perspective-origin:" + xo + "%;-webkit-perspective-origin:" + xo + "%;";
		}
		Box[0].style.cssText = cst;

		var minnum = Math.floor(Dist / Heig) * 2 + 4;
		Deg = 360 / minnum; Deg2 = Deg / 2;
		DegMax = Deg * (Num - 0.65); DegMin = -Deg * 0.35;
		var num2 = Math.floor(Num / 2);
		Cur = Arr[num2];
		Cur.classList.add("sel");
		DegPos = DegCur = Deg * num2;
		Ul.style.cssText = "transform:rotateX(" + DegPos + "deg );-webkit-transform:rotateX(" + DegPos + "deg ));";

		for (var i = 0; i < Num; i++) {
			nd = Arr[i];
			var d = -i * Deg;
			nd.Deg = d;
			d += DegCur;
			if (d > 90 || d < -90) nd.classList.add("off");
			nd.style.cssText = "transform: rotateX(" + nd.Deg + "deg) translateZ(" + z + "px);-webkit-transform:rotateX(" + nd.Deg + "deg ) translateZ(" + z + "px);";
		}

		if (val) selVal(val, true);
	}

	function selVal(val, noevt) {
		if (!val) return;
		val += "";
		var sel = $("li[data-id='" + val + "']", ul);
		if (sel.length < 1) return;
		if (sel.hasClass("hide")) return;
		seled(-sel[0].Deg, noevt);
	}
	function seled(deg, noevt) {
		var n = Math.floor(deg / Deg);
		var d = deg - n * Deg;
		if (d >= Deg2) n += 1;
		var sel = Arr[n];
		if (!sel) { moveDeg(DegCur); return; }
		while (sel.classList.contains("hide")) {
			if (++n >= Num) { moveDeg(DegCur); return; }
			sel = Arr[n];
		}

		deg = n * Deg;
		if (Cur) Cur.classList.remove("sel");
		Cur = Arr[n];
		Cur.classList.add("sel");
		DegCur = deg;
		moveDeg(DegCur);
		if (noevt !== true) Box.triggerHandler("select", Cur.Value);
	}

	var DegPos = 0;
	function moveDeg(deg) {
		if (deg < DegMin) deg = DegMin;
		else if (deg > DegMax) deg = DegMax;
		DegPos = deg;
		for (var i = 0; i < Num; i++) {
			var nd = Arr[i];
			var d = deg + nd.Deg;
			if (d > 90 || d < -90) nd.classList.add("off");
			else nd.classList.remove("off");
		}
		Ul.style.cssText = "transform:rotateX(" + deg + "deg );-webkit-transform:rotateX(" + deg + "deg ));";
	}

	render();

	var Pos = -1;
	Box.on("touchstart", function (evt) { Pos = evt.originalEvent.touches[0].pageY; });
	Box.on("touchend touchcancel", function () { Pos = -1; seled(DegPos); });
	Box.on("touchmove", function (evt) {
	    evt.preventDefault();
		evt.stopPropagation();
		if (Pos < 0) return;
		var pos = evt.originalEvent.touches[0].pageY;
		var dist = Pos - pos;
		if (Math.abs(dist) >= MinDist) {
			Pos = pos;
			var deg = dist * 180 / Dist;
			moveDeg(deg + DegPos);
		}
	});

	return Box;
};


$$.Selector_Circle = function (node, rows, val, clas, xoffset) {
	//完全循环的滚轮选择器
    var Box = $("<div>").addClass("Selector");
    if (clas) Box.addClass(clas);
    Box.Val = function (value) {
        if (value === undefined) {
            if (!Cur) return null;
            return Cur.Value;
        }
        if (!value && value !== 0) return;
        selVal(value, true);
    };
    Box.HideVal = function (val) {
    	var t = $.type(val);
    	if (t === "array") {
            for (var i = 0; i < val.length; i++) {
                $("li[data-id='" + val[i] + "']", ul).addClass("hide");
            }
            return;
    	}
    	if (t === "object") {
    		for (var k in val) {
    			$("li[data-id='" + k + "']", ul).addClass("hide");
    		}
    		return;
    	}
        $("li[data-id='" + val + "']", ul).addClass("hide");
    };
    Box.ShowVal = function (val) {
        if ($.type(val) === "array") {
            for (var i = 0; i < val.length; i++) {
                $("li[data-id='" + val[i] + "']", ul).removeClass("hide");
            }
            return;
        }
        if (t === "object") {
        	for (var k in val) {
        		$("li[data-id='" + k + "']", ul).removeClass("hide");
        	}
        	return;
        }
        $("li[data-id='" + val + "']", ul).removeClass("hide");
    };
    Box.ShowAll = function () {
        $("li.hide", ul).removeClass("hide");
    };

    if (!node) return Box;
    var tp = $.type(rows);
    if (tp !== "array" || rows.length < 1) {
        Box.appendTo(node);
        Box.html("数据加载失败");
        return Box;
    }

    var Arr = [], Cur = null, Dist = 0, Heig = 20, MinDist = 1, DispNum = 0, MinDeg = 360;

    var Deg = 0, Deg2 = 0, DegCur = 0, DegMax = 0, DegMin = 0, DegCircle = 0;
    function render() {
        var nd;
        function rendrow() {
            for (var i = 0; i < rows.length; i++) {
                var row = rows[i];
                nd = $("<li>").attr("data-id", row.ID + "").html(row.Name).appendTo(ul)[0];
                nd.Value = row;
                Arr.push(nd);
            }
        }
        rendrow();
        Box.appendTo(node);
        rendrow();
        Dist = node.clientHeight;
        Heig = Arr[0].clientHeight || Heig;

        var top = (Dist - Heig - 20) / 2;
        Stage.css({ "height": Heig + "px", "top": top + "px" });

        var minnum = Math.floor(Dist / Heig) * 2 + 4;
        while (Arr.length < minnum) { rendrow(); }

        var num = Math.ceil(minnum / 2);
        if (Math.max(num * 3, num * 2 + 15) < Arr.length) DispNum = num;

        var z = Dist / 2 - 2;
        var perspective = z * Dist / Heig;
        var cst = "perspective:" + perspective + "px;-webkit-perspective:" + perspective + "px;";
        if (xoffset > 0 || xoffset < 0) {
        	var xo = 50 - xoffset;
        	cst += "perspective-origin:" + xo + "%;-webkit-perspective-origin:" + xo + "%;";
        }
        Box[0].style.cssText = cst;

        Deg = 360 / minnum; Deg2 = Deg / 2;
        var n = 1;
        while ((DegCircle = n * rows.length * Deg) < 90) { n++; }
        DegCur = DegCircle; DegMax = -90; DegMin = -(Arr.length * Deg - 90);
        Ul.style.cssText = "transform:rotateX(" + DegCur + "deg );-webkit-transform:rotateX(" + DegCur + "deg ));";
        Cur = Arr[rows.length];
        Cur.classList.add("sel");

        for (var i = 0; i < Arr.length; i++) {
            nd = Arr[i];
            var d = -i * Deg;
            nd.Deg = d;
            d += DegCur;
            if (d > 90 || d < -90) nd.classList.add("off");
            nd.style.cssText = "transform: rotateX(" + nd.Deg + "deg) translateZ(" + z + "px);-webkit-transform:rotateX(" + nd.Deg + "deg ) translateZ(" + z + "px);";
        }

        if (val) selVal(val, true);
    }

    function selVal(val, noevt) {
        if (!val) return;
        val += "";
        var sel = $("li[data-id='" + val + "']", ul);
        if (sel.length < 1) return;
        if (sel.hasClass("hide")) return;
        DegCur = -sel[0].Deg;
        seled(noevt);
    }
    function seled(noevt) {
        var deg = DegCur;
        var n = Math.floor(deg / Deg);
        var d = deg - n * Deg;
        if (d >= Deg2) n += 1;
        var sel = Arr[n], num = 0;
        while (sel.classList.contains("hide")) {
            if (++num >= rows.length) break;
            if (++n >= Arr.length) n = 0;
        }

        deg = -n * Deg;
        if (deg < DegMin) {
            deg += DegCircle;
            n -= rows.length;
        }
        else if (deg > DegMax) {
            deg -= DegCircle;
            n += rows.length;
        }
        if (Cur) Cur.classList.remove("sel");
        Cur = Arr[n]; 
        Cur.classList.add("sel");
        DegCur = deg = -deg;
        for (var i = 0; i < Arr.length; i++) {
            var nd = Arr[i];
            d = deg + nd.Deg;
            if (d > 90 || d < -90) nd.classList.add("off");
            else nd.classList.remove("off");
        }
        Ul.style.cssText = "transform:rotateX(" + deg + "deg );-webkit-transform:rotateX(" + deg + "deg ));";
        if (noevt !== true) Box.triggerHandler("select", Cur.Value);
    }
    function selDeg(deg) {
        if (deg < DegMin) deg += DegCircle;
        else if (deg > DegMax) deg -= DegCircle;
        DegCur = deg = -deg;
        for (var i = 0; i < Arr.length; i++) {
            var nd = Arr[i];
            var d = deg + nd.Deg;
            if (d > 90 || d < -90) nd.classList.add("off");
            else nd.classList.remove("off");
        }
        Ul.style.cssText = "transform:rotateX(" + deg + "deg );-webkit-transform:rotateX(" + deg + "deg ));";
    }

    var Stage = $("<div>").addClass("Stage").appendTo(Box);
    var ul = $("<ul>").appendTo(Stage);
    var Ul = ul[0];
    render();

    var pos0 = -1;
    Box.on("touchstart", function (evt) { pos0 = evt.originalEvent.touches[0].pageY; });
    Box.on("touchend touchcancel", function () { pos0 = -1; seled(); });
    Box.on("touchmove", function (evt) {
        evt.stopPropagation();
        if (pos0 < 0) return;
        var pos = evt.originalEvent.touches[0].pageY;
        var dist = pos0 - pos;
        if (Math.abs(dist) >= MinDist) {
            pos0 = pos;
            var deg = dist * 180 / Dist;
            deg = -(DegCur + deg);
            selDeg(deg);
        }
    });

    return Box;
};


//低配置手机使用
$$.Selector_Low = function (node, rows, orival, clas, xoffset) {
	var IDs = {}, Sel = null;

	var Box = $("<ul>").addClass("SelectorLow Scroller");
	if (clas) Box.addClass(clas);

	Box.Val = function (val) {
		if (val === undefined) {
			if (!Sel) return {};
			return Sel[0].Value;
		}
		if (!val && val !== 0) return;
		var nod = IDs[val + ""];
		if (!nod || nod.hasClass("hide")) return;
		if (Sel) Sel.removeClass("sel");
		Sel = nod.addClass("sel");
		nod[0].scrollIntoView(false);
	};
	Box.HideVal = function (val) {
		var nod = null;
		var t = $.type(val);
		if (t === "array") {
			for (var i = 0; i < val.length; i++) {
				nod = IDs[val[i] + ""];
				if (nod) nod.addClass("hide");
			}
			return;
		}
		if (t === "object") {
			for (var k in val) {
				nod = IDs[k + ""];
				if (nod) nod.addClass("hide");
			}
			return;
		}
		nod = IDs[val + ""];
		if (nod) nod.addClass("hide");
	};
	Box.ShowVal = function (val) {
		var nod = null;
		var t = $.type(val);
		if (t === "array") {
			for (var i = 0; i < val.length; i++) {
				nod = IDs[val[i] + ""];
				if (nod) nod.removeClass("hide");
			}
			return;
		}
		if (t === "object") {
			for (var k in val) {
				nod = IDs[k + ""];
				if (nod) nod.removeClass("hide");
			}
			return;
		}
		nod = IDs[val + ""];
		if(nod) nod.removeClass("hide");
	};
	Box.ShowAll = function () {
		$("li.hide", Box).removeClass("hide");
	};

	if (!node) return Box;
	var tp = $.type(rows);
	if (tp !== "array" || rows.length < 1) {
		Box.html("<li>数据加载失败</li>");
		if (node) Box.appendTo(node);
		return Box;
	}

	function selnod(evt) {
		var nod = $(this);
		if (nod.hasClass("hide")) return;
		if (Sel) Sel.removeClass("sel");
		Sel = nod.addClass("sel");
		Box.triggerHandler("select", Sel[0].Value);
	}

	for (var i = 0; i < rows.length; i++) {
		var row = rows[i];
		if (!row || !(row.ID || row.ID ==0)) continue;
		var nod = $("<li>").html(row.Name + "").appendTo(Box);
		nod.on("click", selnod);
		nod[0].Value = row;
		IDs[row.ID + ""] = nod;
		if (!Sel) Sel = nod.addClass("sel");
	}
	Box.appendTo(node);
	if (!Sel) {
		Box.html("数据为空");
		return Box;
	}

	if (orival) Box.Val(orival);
	return Box;
};